package nl.leiden.activities;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

import nl.leiden.R;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Vibrator;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;
import android.view.View;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.Prediction;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.preference.PreferenceManager;
import android.provider.Contacts;
import android.provider.ContactsContract;
import android.provider.Contacts.People;
import android.provider.ContactsContract.PhoneLookup;

public class ContactsActivity extends Activity implements OnGesturePerformedListener {

	//----------------------------------------------------
	
	private String number = new String();
    private StringBuffer numberBuffer = new StringBuffer();
    
	private GestureLibrary gesturesLibActions;
	private GestureLibrary gesturesLibStandard;
	private GestureLibrary gesturesLibUser;
	
	private final File gesturesLibUserFile = new File(Environment.getExternalStorageDirectory(), "gestures_lib_user");
	
	private int counter;
	Map<String, String> phoneNumbersMap = new HashMap<String, String>();
	Map<String, String> contactsMap = new HashMap<String, String>();
	
	//----------------------------------------------------
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_contacts);
    
        
        
		Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		v.vibrate(200);
		counter = 0;
        
        /*Button next = (Button) findViewById(R.id.ButtonContactsNext);
        next.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent myIntent = new Intent(view.getContext(), WritingActivity.class);
                startActivityForResult(myIntent, 0);
            }

        });*/
        
        //-- load gesture libraries
        gesturesLibActions = GestureLibraries.fromRawResource(this, R.raw.gestures_lib_actions);
        if(!this.gesturesLibActions.load()) {
        	this.finish();
        }
        
        gesturesLibStandard = GestureLibraries.fromRawResource(this, R.raw.gestures_lib_standard);
        if(!this.gesturesLibStandard.load()) {
        	this.finish();
        }
        
        //----TODO: CHECK IF FILE IS EXISTING OR NOT
        gesturesLibUser = GestureLibraries.fromFile(gesturesLibUserFile);
        if(!this.gesturesLibUser.load()) {
        	this.finish();
        }  
        
        //-- get gesture overlay view to add on gesture performed listener
        GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
        gestures.addOnGesturePerformedListener(this);
        
        TextView tv = (TextView) findViewById(R.id.ContactTextView);
        tv.setCursorVisible(true);
        tv.setText(number + "|");
        
        //--load contacts
        //loadContacts("Leroy van Delft");
        
    }
    
    //----------------------------------------------------
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
    	//--recognize libraries
    	ArrayList<Prediction> predictionsActions = gesturesLibActions.recognize(gesture);
    	ArrayList<Prediction> predictionsStandard = gesturesLibStandard.recognize(gesture);
		ArrayList<Prediction> predictionsUser = gesturesLibUser.recognize(gesture);
				
		ArrayList<Prediction> predictionsAll = new ArrayList<Prediction>();
		predictionsAll.addAll(predictionsActions);
		predictionsAll.addAll(predictionsStandard);
		predictionsAll.addAll(predictionsUser);
			
		//--when added the other predictions, need to re sort the predictionsAll ArrayList again	
		//--http://ventrix.nsdc.gr/code_folds/?p=119
		Comparator<Prediction> comparator = new Comparator<Prediction>() {
			//@Override
			public int compare(Prediction object1, Prediction object2) {
				if( object1.score > object2.score ) {
					return -1;
				} else if (object1.score < object2.score ) {
					return 1;
				} else {
					return 0;
				}			
			}
		};
		Collections.sort(predictionsAll, comparator);
		
		// We want at least one prediction
		if (predictionsActions.size() > 0) {
			Prediction prediction = predictionsAll.get(0);
			// We want at least some confidence in the result
			if (prediction.score > 1.5) {
				
				//--action name
				String action = predictionsAll.get(0).name;
				
				//--action: confirm
				if ("action_confirm".equals(action) ) {
					
					if( this.numberBuffer.length() >= 2 || this.phoneNumbersMap.isEmpty() == false) {
						/***
						 * TODO:
						 * Add all this to a for-loop to use user input
						 * Use the iterator of the for-loop as the key for the items in the map
						 * Don't forget to cast it to a string
						 */
						
						//phoneNumbersMap.put("0", "0683538287");
						//contactsMap.put("0", "Leroy");
						
						//--load contacts
						loadContacts(number);
						
				        SharedPreferences phoneNumbers = getBaseContext().getSharedPreferences("phonenumber_list", MODE_PRIVATE);
				        SharedPreferences.Editor phoneNumbersEditor = phoneNumbers.edit();
				        for (String s : phoneNumbersMap.keySet()){
				        	phoneNumbersEditor.putString(s, phoneNumbersMap.get(s));
				        }
						phoneNumbersEditor.commit();
						
				        SharedPreferences contacts = getBaseContext().getSharedPreferences("contact_list", MODE_PRIVATE);
				        SharedPreferences.Editor contactsEditor = contacts.edit();
				        for (String s : contactsMap.keySet()){
				        	contactsEditor.putString(s, contactsMap.get(s));
				        }
						contactsEditor.commit();
						
						//String Number = phoneNumbers.getString("0", "");
				        
				        //Toast.makeText(this, Number, Toast.LENGTH_SHORT).show();	        
						
						Intent myIntent = new Intent(this, WritingActivity.class);
		                startActivityForResult(myIntent, 0);
					} else {
						Toast.makeText(this, "Warning: name must consist of at least 2 characters", Toast.LENGTH_SHORT).show();
					}
				}
				
				else if ("action_backspace".equals(action)) {
					if(this.numberBuffer.length() >= 1) {
						this.numberBuffer.deleteCharAt(this.numberBuffer.length()-1);
						this.number = this.numberBuffer.toString();
					} 
				}
				
				//--action: add
				else if ("action_add".equals(action)) {
					
					if( this.numberBuffer.length() >= 2 || this.phoneNumbersMap.isEmpty() == false) {
					
						//--give vibration feedback
				        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
						v.vibrate(200);
						
						//String j = Integer.toString(counter);
						//phoneNumbersMap.put(j, number);
				        loadContacts(number);
				        
				        if(this.numberBuffer.length() >= 1) {
							this.numberBuffer.delete(0, this.numberBuffer.length() );
							this.number = this.numberBuffer.toString();
						}
						TextView tv = (TextView) findViewById(R.id.ContactTextView);
				        tv.setText(number + "|");
						
						//Toast.makeText(this, "added phonenumber", Toast.LENGTH_SHORT).show();
					} else {
						Toast.makeText(this, "Warning: name must consist of at least 2 characters", Toast.LENGTH_SHORT).show();
					}
				}
				
				//--action: clear
				else if ("action_clear".equals(action)) {
					for(int i = 0; i < 300; i++){
						String j = Integer.toString(i);
						SharedPreferences phoneNumbers = getBaseContext().getSharedPreferences("phonenumber_list", MODE_PRIVATE);
						SharedPreferences.Editor phoneNumbersEditor = phoneNumbers.edit();
						SharedPreferences contacts = getBaseContext().getSharedPreferences("contact_list", MODE_PRIVATE);
				        SharedPreferences.Editor contactsEditor = contacts.edit();
						if (phoneNumbers.contains(j)){
				        	phoneNumbersEditor.clear();
				        	phoneNumbersEditor.commit();
							contactsEditor.clear();
							contactsEditor.commit();
						}
						else { 
							i = 301;
						}
					}
					this.phoneNumbersMap.clear();
					this.contactsMap.clear();
					
					//--clear text on screen
					if(this.numberBuffer.length() >= 1) {
						this.numberBuffer.delete(0, this.numberBuffer.length() );
						this.number = this.numberBuffer.toString();
					}
					TextView tv = (TextView) findViewById(R.id.ContactTextView);
			        tv.setText(number + "|");
					
					Toast.makeText(this, "cleared recipients", Toast.LENGTH_SHORT).show();
				}
				
				//--action: goback
				else if ("action_goback".equals(action)) {
					Toast.makeText(this, "go back not applicable gesture", Toast.LENGTH_SHORT).show();
				}
				
				//--add gesture number to array
				else {
					// Show the spell
					//Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
				
					//-- use a string buffer to add the new character to the message
					//-- .append at string buffer is 300 times faster than string s += " string to add"
					this.numberBuffer.append( prediction.name );
					this.number = numberBuffer.toString();
				}
				//Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
				
				//-- set text view with updated message
				TextView tv = (TextView) findViewById(R.id.ContactTextView);
		        tv.setText(this.number + "|");
				

			} else {
				Toast.makeText(this, "gesture not recognized", Toast.LENGTH_SHORT).show();
			}
		}
	}
    
    //----------------------------------------------------
    public void loadContacts(String _contactName) {
    	
    	/***
    	 * WARNING: TEXT VIEW IS DISABLED IN MAIN_CONTACTS.XML FOR THE PURPOSE OF NOT CRASHING
    	 */
    	
    	//-- http://stackoverflow.com/questions/1721279/how-to-read-contacts-on-android-2-0
    	//-- http://mobile.tutsplus.com/tutorials/android/android-essentials-using-the-contact-picker/
    	//-- http://stackoverflow.com/questions/4301064/how-to-get-the-firstname-and-lastname-from-android-contacts
    	//-- http://www.drupal.javatomic.com/java-blog/android-get-contacts-with-phone-number
    	//-- http://stackoverflow.com/questions/5485940/android-get-contacts-name-and-number-query
    	//-- http://developer.android.com/resources/articles/contacts.html
    	//-- http://developer.android.com/guide/topics/providers/content-providers.html#querying
    	//-- http://stackoverflow.com/questions/866769/how-to-call-android-contacts-list
    	
    	//--select contacts with a phone number
    	Uri contactUri = ContactsContract.Contacts.CONTENT_URI;

        String[] PROJECTION = new String[] {
                ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME
        };

        //String SELECTION = ContactsContract.Contacts.HAS_PHONE_NUMBER + "='1'";
        //String SELECTION = ContactsContract.Contacts.DISPLAY_NAME + "='Arne Boon'";
        String SELECTION = ContactsContract.Contacts.DISPLAY_NAME + " like '%"  + _contactName + "%'";
    	Cursor contacts = managedQuery(contactUri, PROJECTION, SELECTION, null, null );
    	
    	//-- resolve content
        ContentResolver contentResolver = getContentResolver();
     
        while (contacts.moveToNext() ) {
            String id = contacts.getString(contacts.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
            String name = "";
            String phoneNumber = "";

            Cursor phoneCur = contentResolver.query(
            		ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
            		null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", 
                    new String[] { id }, 
                    null);

            if (phoneCur.moveToNext()) {
                name = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                phoneNumber = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                
                if (name != "" && phoneNumber != ""){
            	
    	            String j = Integer.toString(counter);
    	            this.phoneNumbersMap.put(j, phoneNumber);
    	            this.contactsMap.put(j, name);
    	            
    	            Toast.makeText(this, "Sending to: " + name + " at phonenumber: " + phoneNumber + " [nr: " + counter + "]", Toast.LENGTH_LONG).show();
    	            Log.e("Phone no & name :***: ", name + " : " + phoneNumber + "  nr: " + counter);
    	            
    	            counter++;
                }
            }

            id = null;
            name = null;
            phoneNumber = null;
            phoneCur = null;
        }
        
        contacts.close();
        contentResolver = null;
        contacts = null;
        
        //populateContacts();
        
        /*
        String whereName = ContactsContract.Data.MIMETYPE + " = ?";
        String[] whereNameParams = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
        Cursor nameCur = contentResolver.query(
        	ContactsContract.Data.CONTENT_URI, 
        	null, 
        	whereName, 
        	whereNameParams, 
        	ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
        while (nameCur.moveToNext()) {
            String given = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
            String family = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
            String display = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
        }
        nameCur.close();*/

    }
    
}
